home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / utils / sortsrc.arc / sortcomp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-06  |  21.0 KB  |  719 lines

  1. /******************************************************************************
  2.  *                                                                            *
  3.  *   sortcomp.c  version 1.0 of  1 Januari 1989    (C) L.J.M. de Wit 1989     *
  4.  *                                                                            *
  5.  * This software may be used and distributed freely if not used commercially  *
  6.  * and the originator (me) is mentioned in the source (just leave this 9 line *
  7.  * header intact).                                                            *
  8.  *                                                                            *
  9.  ******************************************************************************
  10.  *
  11.  * sortcomp.c: comparision functions
  12.  *
  13.  * These functions contain the numeric comparision functions c_n and its
  14.  * reverse, c_nr. The other 48 comparision functions are formed by combining
  15.  * the following properties (take note of the Capitals):
  16.  *  a) either Dictionary, Ignore non-printables or Any other        (3)
  17.  *  b) ignore leading Blanks, versus not ignoring them              (2)
  18.  *  c) Fold upper case to lower, versus not folding                 (2)
  19.  *  d) Reverse the result of the comparision, versus not reversing  (2)
  20.  *  e) Unbounded (bounded only by '\0'), versus upper limit bound   (2)
  21.  *
  22.  * Since comparing is done a lot it is important for the compare functions
  23.  * to be fast. As for using the 48 functions as it stands the following
  24.  * arguments are used:
  25.  * One could have combined functions and used flags to discern between options.
  26.  * This would however involve passing more parameters to the function (the
  27.  * flags) and would require (perhaps a lot of) unwanted testing inside the
  28.  * function.
  29.  * Several functions call one of the other functions. This has been done in
  30.  * such a way that duplication of code is mostly prevented, but still this call
  31.  * is limited to only one (both in number and in level).
  32.  * The numerical compare could have been done by a simple atoi(), but the
  33.  * c_n function does the comparision inline, and stops comparing when the
  34.  * bigger one has been found (while atoi needs to do calculation ala
  35.  * 10 * num + digit, and will use all digits).
  36.  */
  37.  
  38. #include <stdio.h>
  39. #include <ctype.h>
  40. #include "sortmain.h"
  41. #include "sortcomp.h"
  42.  
  43. #define SKIPSPACE(bs,bt) while (wspace(*(bs))) (bs)++; while (wspace(*(bt))) (bt)++
  44.  
  45. #define NCHARS  256
  46. #define NORM 0x1
  47. #define DICT 0x2
  48. #define isnorm(c)   (stype[(c)]&NORM)
  49. #define isdict(c)   (stype[(c)]&DICT)
  50.  
  51. #undef  isdigit
  52. #define isdigit(c) ((c) >= '0' && (c) <= '9')
  53.  
  54. static char fold[NCHARS];                       /* For lcase conversion     */
  55.  
  56. static char stype[NCHARS];                      /* For table lookup         */
  57.  
  58. void initlookup()                               /* Initialize lookup tables */
  59. {
  60.     register int i;
  61.  
  62.     for (i = 0; i < NCHARS; i++) {
  63.         fold[i] = isupper(i) ? tolower(i) : i;  /* Init lcase convert array */
  64.         stype[i] = 0;                           /* Not really needed ...    */
  65.         if (i >= 040 && i <= 0176) {            /* Ascii non-control        */
  66.             stype[i] |= NORM;
  67.         }
  68.         if (wspace(i) || isalnum(i)) {          /* Whitespace & alphanum    */
  69.             stype[i] |= DICT;
  70.         }
  71.     }
  72. }
  73.  
  74. int c_nr(bs,bt,es,et)                           /* Reversed Numeric         */
  75. char *bs, *bt;
  76. char *es, *et;
  77. {
  78.     return c_n(bt,bs,et,es);
  79. }
  80.  
  81. int c_n(bs,bt,es,et)                            /* Numeric compare          */
  82. register char *bs, *bt;
  83. char *es, *et;
  84. {
  85.     register int rev, mini;
  86.  
  87.     SKIPSPACE(bs,bt);
  88.     if (*bs == '-') {
  89.         if (*bt == '-') {                       /* Two negatives: reverse   */
  90.             rev = -1;
  91.             bs++;
  92.             bt++;
  93.         } else {                                /* bt will be the larger one*/
  94.             return -1;
  95.         }
  96.     } else {
  97.         if (*bt == '-') {                       /* bs will be the larger one*/
  98.             return 1;
  99.         } else {
  100.             rev = 1;                            /* Both positive            */
  101.         }
  102.     }
  103.  
  104.     while (*bs == *bt && isdigit(*bt)) {        /* Compare & skip eq. digits*/
  105.         bs++; bt++;
  106.     }
  107.  
  108.     if (!isdigit(*bs)) {
  109.         if (!isdigit(*bt)) {
  110.             if (*bs == '.' && *bt == '.') {     /* Decimal point            */
  111.                 while (*++bs == *++bt && isdigit(*bt)) ;
  112.                 while (*bs == '0') bs++;        /* Skip possibly trailing   */
  113.                 while (*bt == '0') bt++;        /*     zeroes               */
  114.                 if (!isdigit(*bs)) {
  115.                     if (!isdigit(*bt)) {
  116.                         return 0;               /* Tails also equal         */
  117.                     }
  118.                     return -rev;                /* bt has more digits       */
  119.                 }
  120.                 if (!isdigit(*bt)) {
  121.                     return rev;                 /* bs has more digits       */
  122.                 }
  123.                 return (rev == 1)               /* Current digit decides    */
  124.                        ? (*bs - *bt) : (*bt - *bs);
  125.             } else {
  126.                 return 0;                       /* Equal numeric strings    */
  127.             }
  128.         }
  129.         return -rev;                            /* bt has more digits       */
  130.     }
  131.     if (!isdigit(*bt)) {
  132.         return rev;                             /* bs has more digits       */
  133.     }
  134.     mini = (rev == 1)                           /* Current digit decides:   */
  135.            ? (*bs - *bt) : (*bt - *bs);         /* Difference into mini     */
  136.     do {
  137.         bs++;
  138.         bt++;
  139.     } while (isdigit(*bs) && isdigit(*bt));     /* Skip any more digits     */
  140.  
  141.     if (!isdigit(*bs)) {
  142.         if (!isdigit(*bt)) {                    /* Strings equally long:    */
  143.             return mini;                        /* then mini decides        */
  144.         }
  145.         return -rev;                            /* bt has more digits       */
  146.     }
  147.     return rev;                                 /* bs has more digits       */
  148. }
  149.  
  150. int c_df(bs,bt,es,et)                           /* Dictionary/Fold          */
  151. register char *bs, *bt;                         /* Strings to compare       */
  152. register char *es, *et;
  153. {
  154.     --bs;   --bt;   --es;   --et;
  155.     for ( ; bs < es && bt < et; ) {
  156.         if (fold[*++bs] != fold[*++bt]) {       /* Increment & compare      */
  157.             if (isdict(*bs)) {
  158.                 if (isdict(*bt)) {
  159.                     return fold[*bs] - fold[*bt];
  160.                 } else {
  161.                     --bs;                       /* Effectively skip *bt     */
  162.                 }
  163.             } else if (isdict(*bt)) {
  164.                 --bt;                           /* Effectively skip *bs     */
  165.             }                                   /* (else: skip both)        */
  166.         }
  167.     }
  168.     for ( ; bs < es; ) {                        /* Skip any more            */
  169.         if (isdict(*++bs)) {                    /* non-dict chars in bs     */
  170.             --bs;
  171.             break;
  172.         }
  173.     }
  174.     for ( ; bt < et; ) {                        /* Skip any more            */
  175.         if (isdict(*++bt)) {                    /* non-dict chars in bt     */
  176.             --bt;
  177.             break;
  178.         }
  179.     }
  180.  
  181.     return (et - bt) - (es - bs);
  182. }
  183.  
  184. int c_d(bs,bt,es,et)                            /* Dictionary order         */
  185. register char *bs, *bt;
  186. register char *es, *et;
  187. {
  188.     --bs;   --bt;   --es;   --et;
  189.     for ( ; bs < es && bt < et; ) {
  190.         if (*++bs != *++bt) {                   /* Increment & compare      */
  191.             if (isdict(*bs)) {
  192.                 if (isdict(*bt)) {
  193.                     return fold[*bs] - fold[*bt];
  194.                 } else {
  195.                     --bs;                       /* Effectively skip *bt     */
  196.                 }
  197.             } else if (isdict(*bt)) {
  198.                 --bt;                           /* Effectively skip *bs     */
  199.             }                                   /* (else: skip both)        */
  200.         }
  201.     }
  202.     for ( ; bs < es; ) {                        /* Skip any more            */
  203.         if (isdict(*++bs)) {                    /* non-dict chars in bs     */
  204.             --bs;
  205.             break;
  206.         }
  207.     }
  208.     for ( ; bt < et; ) {                        /* Skip any more            */
  209.         if (isdict(*++bt)) {                    /* non-dict chars in bt     */
  210.             --bt;
  211.             break;
  212.         }
  213.     }
  214.  
  215.     return (et - bt) - (es - bs);
  216. }
  217.  
  218. int c_if(bs,bt,es,et)                           /* Normalized/Fold          */
  219. register char *bs, *bt;
  220. register char *es, *et;
  221. {
  222.     --bs;   --bt;   --es;   --et;
  223.     for ( ; bs < es && bt < et; ) {
  224.         if (fold[*++bs] != fold[*++bt]) {       /* Increment & compare      */
  225.             if (isnorm(*bs)) {
  226.                 if (isnorm(*bt)) {
  227.                     return fold[*bs] - fold[*bt];
  228.                 } else {
  229.                     --bs;                       /* Effectively skip *bt     */
  230.                 }
  231.             } else if (isnorm(*bt)) {
  232.                 --bt;                           /* Effectively skip *bs     */
  233.             }                                   /* (else: skip both)        */
  234.         }
  235.     }
  236.     for ( ; bs < es; ) {                        /* Skip any more            */
  237.         if (isnorm(*++bs)) {                    /* non-norm chars in bs     */
  238.             --bs;
  239.             break;
  240.         }
  241.     }
  242.     for ( ; bt < et; ) {                        /* Skip any more            */
  243.         if (isnorm(*++bt)) {                    /* non-norm chars in bt     */
  244.             --bt;
  245.             break;
  246.         }
  247.     }
  248.  
  249.     return (et - bt) - (es - bs);
  250. }
  251.  
  252. int c_i(bs,bt,es,et)                            /* Normalized order         */
  253. register char *bs, *bt;
  254. register char *es, *et;
  255. {
  256.     --bs;   --bt;   --es;   --et;
  257.     for ( ; bs < es && bt < et; ) {
  258.         if (*++bs != *++bt) {                   /* Increment & compare      */
  259.             if (isnorm(*bs)) {
  260.                 if (isnorm(*bt)) {
  261.                     return fold[*bs] - fold[*bt];
  262.                 } else {
  263.                     --bs;                       /* Effectively skip *bt     */
  264.                 }
  265.             } else if (isnorm(*bt)) {
  266.                 --bt;                           /* Effectively skip *bs     */
  267.             }                                   /* (else: skip both)        */
  268.         }
  269.     }
  270.     for ( ; bs < es; ) {                        /* Skip any more            */
  271.         if (isnorm(*++bs)) {                    /* non-norm chars in bs     */
  272.             --bs;
  273.             break;
  274.         }
  275.     }
  276.     for ( ; bt < et; ) {                        /* Skip any more            */
  277.         if (isnorm(*++bt)) {                    /* non-norm chars in bt     */
  278.             --bt;
  279.             break;
  280.         }
  281.     }
  282.  
  283.     return (et - bt) - (es - bs);
  284. }
  285.  
  286. int c_af(bs,bt,es,et)                           /* Fold                     */
  287. register char *bs, *bt;
  288. register char *es, *et;
  289. {
  290.     register short minlen;
  291.  
  292.     minlen = ((es - bs) <= (et - bt)) ? (es - bs) : (et - bt);
  293.     if (minlen == 0) {
  294.         return (es - bs) - (et - bt);
  295.     }
  296.  
  297.     if (fold[*bs] == fold[*bt]) {
  298.         for ( ; --minlen != 0 && fold[*++bs] == fold[*++bt]; ) ;
  299.         if (minlen == 0) {
  300.             return 0;
  301.         }
  302.     }
  303.  
  304.     return fold[*bs] - fold[*bt];
  305. }
  306.  
  307. int c_dfu(bs,bt)                                /* Dictionary/Fold          */
  308. register char *bs, *bt;
  309. {
  310.     register char *fld = fold;
  311.  
  312.     --bs; --bt;
  313.     do {
  314.         while (fld[*++bs] == fld[*++bt] && *bt) ; /* Skip equal ones      */
  315.         if (!*bt || !*bs) break;                /* Stop on '\0'             */
  316.         if (isdict(*bs)) {
  317.             if (isdict(*bt)) {
  318.                 break;                          /* Difference found         */
  319.             } else {
  320.                 --bs;                           /* Effectively skip *bt     */
  321.             }
  322.         } else {
  323.             if (isdict(*bt)) {
  324.                 --bt;                           /* Effectively skip *bs     */
  325.             }
  326.         }                                       /* (else: skip both)        */
  327.     } while (1);
  328.  
  329.     return fld[*bs] - fld[*bt];
  330. }
  331.  
  332. int c_du(bs,bt)                                 /* Dictionary               */
  333. register char *bs, *bt;
  334. {
  335.     --bs; --bt;
  336.     do {
  337.         while (*++bs == *++bt && *bt) ;         /* Skip equal ones      */
  338.         if (!*bt || !*bs) break;                /* Stop on '\0'             */
  339.         if (isdict(*bs)) {
  340.             if (isdict(*bt)) {
  341.                 break;                          /* Difference found         */
  342.             } else {
  343.                 --bs;                           /* Effectively skip *bt     */
  344.             }
  345.         } else {
  346.             if (isdict(*bt)) {
  347.                 --bt;                           /* Effectively skip *bs     */
  348.             }
  349.         }                                       /* (else: skip both)        */
  350.     } while (1);
  351.  
  352.     return *bs - *bt;
  353. }
  354.  
  355. int c_ifu(bs,bt)                                /* Normalized/Fold          */
  356. register char *bs, *bt;
  357. {
  358.     register char *fld = fold;
  359.  
  360.     --bs; --bt;
  361.     do {
  362.         while (fld[*++bs] == fld[*++bt] && *bt) ; /* Skip equal ones      */
  363.         if (!*bt || !*bs) break;                /* Stop on '\0'             */
  364.         if (isnorm(*bs)) {
  365.             if (isnorm(*bt)) {
  366.                 break;                          /* Difference found         */
  367.             } else {
  368.                 --bs;                           /* Effectively skip *bt     */
  369.             }
  370.         } else {
  371.             if (isnorm(*bt)) {
  372.                 --bt;                           /* Effectively skip *bs     */
  373.             }
  374.         }                                       /* (else: skip both)        */
  375.     } while (1);
  376.  
  377.     return fld[*bs] - fld[*bt];
  378. }
  379.  
  380. int c_iu(bs,bt)                                 /* Normalized               */
  381. register char *bs, *bt;
  382. {
  383.     --bs; --bt;
  384.     do {
  385.         while (*++bs == *++bt && *bt) ;         /* Skip equal ones      */
  386.         if (!*bt || !*bs) break;                /* Stop on '\0'             */
  387.         if (isnorm(*bs)) {
  388.             if (isnorm(*bt)) {
  389.                 break;                          /* Difference found         */
  390.             } else {
  391.                 --bs;                           /* Effectively skip *bt     */
  392.             }
  393.         } else {
  394.             if (isnorm(*bt)) {
  395.                 --bt;                           /* Effectively skip *bs     */
  396.             }
  397.         }                                       /* (else: skip both)        */
  398.     } while (1);
  399.  
  400.     return *bs - *bt;
  401. }
  402.  
  403. int c_afu(bs,bt)                                /* Fold                     */
  404. register char *bs, *bt;
  405. {
  406.     register char *fld = fold;
  407.  
  408.     if (fld[*bs] == fld[*bt] && *bt) {
  409.         for ( ; fld[*++bs] == fld[*++bt] && *bt; ) ;
  410.     }
  411.  
  412.     return fld[*bs] - fld[*bt];
  413. }
  414.  
  415. #ifndef M68000
  416. /* using asm if 68000 */
  417.  
  418. int c_dbfr(bs,bt,es,et)                         /* Dict/Blank/Fold/Reverse  */
  419. register char *bs, *bt;
  420. char *es, *et;
  421. {
  422.     SKIPSPACE(bs,bt);
  423.     return c_df(bt,bs,et,es);
  424. }
  425.  
  426. int c_dbf(bs,bt,es,et)                          /* Dictionary/Blank/Fold    */
  427. register char *bs, *bt;
  428. char *es, *et;
  429. {
  430.     SKIPSPACE(bs,bt);
  431.     return c_df(bs,bt,es,et);
  432. }
  433.  
  434. int c_dbr(bs,bt,es,et)                          /* Dictionary/Blank/Reverse */
  435. register char *bs, *bt;
  436. char *es, *et;
  437. {
  438.     SKIPSPACE(bs,bt);
  439.     return c_d(bt,bs,et,es);
  440. }
  441.  
  442. int c_db(bs,bt,es,et)                           /* Dictionary/Blank         */
  443. register char *bs, *bt;
  444. char *es, *et;
  445. {
  446.     SKIPSPACE(bs,bt);
  447.     return c_d(bs,bt,es,et);
  448. }
  449.  
  450. int c_dfr(bs,bt,es,et)                          /* Dictionary/Fold/Reverse  */
  451. char *bs, *bt;
  452. char *es, *et;
  453. {
  454.     return c_df(bt,bs,et,es);
  455. }
  456.  
  457. int c_dr(bs,bt,es,et)                           /* Dictionary/Reversed      */
  458. char *bs, *bt;
  459. char *es, *et;
  460. {
  461.     return c_d(bt,bs,et,es);
  462. }
  463.  
  464. int c_ibfr(bs,bt,es,et)                         /* Norm/Blank/Fold/Reverse  */
  465. register char *bs, *bt;
  466. char *es, *et;
  467. {
  468.     SKIPSPACE(bs,bt);
  469.     return c_if(bt,bs,et,es);
  470. }
  471.  
  472. int c_ibf(bs,bt,es,et)                          /* Normalized/Blank/Fold    */
  473. register char *bs, *bt;
  474. char *es, *et;
  475. {
  476.     SKIPSPACE(bs,bt);
  477.     return c_if(bs,bt,es,et);
  478. }
  479.  
  480. int c_ibr(bs,bt,es,et)                          /* Normalized/Blank/Reverse */
  481. register char *bs, *bt;
  482. char *es, *et;
  483. {
  484.     SKIPSPACE(bs,bt);
  485.     return c_i(bt,bs,et,es);
  486. }
  487.  
  488. int c_ib(bs,bt,es,et)                           /* Normalized/Blank         */
  489. register char *bs, *bt;
  490. char *es, *et;
  491. {
  492.     SKIPSPACE(bs,bt);
  493.     return c_i(bs,bt,es,et);
  494. }
  495.  
  496. int c_ifr(bs,bt,es,et)                          /* Normalized/Fold/Reverse  */
  497. char *bs, *bt;
  498. char *es, *et;
  499. {
  500.     return c_if(bt,bs,et,es);
  501. }
  502.  
  503. int c_ir(bs,bt,es,et)                           /* Normalized/Reversed      */
  504. char *bs, *bt;
  505. char *es, *et;
  506. {
  507.     return c_i(bt,bs,et,es);
  508. }
  509.  
  510. int c_abfr(bs,bt,es,et)                         /* Blank/Fold/Reverse       */
  511. register char *bs, *bt;
  512. char *es, *et;
  513. {
  514.     SKIPSPACE(bs,bt);
  515.     return c_af(bt,bs,et,es);
  516. }
  517.  
  518. int c_abf(bs,bt,es,et)                          /* Blank/Fold               */
  519. register char *bs, *bt;
  520. char *es, *et;
  521. {
  522.     SKIPSPACE(bs,bt);
  523.     return c_af(bs,bt,es,et);
  524. }
  525.  
  526. int c_abr(bs,bt,es,et)                          /* Blank/Reverse            */
  527. register char *bs, *bt;
  528. char *es, *et;
  529. {
  530.     SKIPSPACE(bs,bt);
  531.     return c_a(bt,bs,et,es);
  532. }
  533.  
  534. int c_ab(bs,bt,es,et)                           /* Blank                    */
  535. register char *bs, *bt;
  536. char *es, *et;
  537. {
  538.     SKIPSPACE(bs,bt);
  539.     return c_a(bs,bt,es,et);
  540. }
  541.  
  542. int c_afr(bs,bt,es,et)                          /* Fold/Reverse             */
  543. char *bs, *bt;
  544. char *es, *et;
  545. {
  546.     return c_af(bt,bs,et,es);
  547. }
  548.  
  549. int c_ar(bs,bt,es,et)                           /* Reverse                  */
  550. char *bs, *bt;
  551. char *es, *et;
  552. {
  553.     return c_a(bt,bs,et,es);
  554. }
  555.  
  556. /* Unbounded comparisions start here */
  557.  
  558. int c_dbfru(bs,bt)                              /* Dict/Blank/Fold/Reverse  */
  559. register char *bs, *bt;
  560. {
  561.     SKIPSPACE(bs,bt);
  562.     return c_dfu(bt,bs);
  563. }
  564.  
  565. int c_dbfu(bs,bt)                               /* Dictionary/Blank/Fold    */
  566. register char *bs, *bt;
  567. {
  568.     SKIPSPACE(bs,bt);
  569.     return c_dfu(bs,bt);
  570. }
  571.  
  572. int c_dbru(bs,bt)                               /* Dictionary/Blank/Reverse */
  573. register char *bs, *bt;
  574. {
  575.     SKIPSPACE(bs,bt);
  576.     return c_du(bt,bs);
  577. }
  578.  
  579. int c_dbu(bs,bt)                                /* Dictionary/Blank         */
  580. register char *bs, *bt;
  581. {
  582.     SKIPSPACE(bs,bt);
  583.     return c_du(bs,bt);
  584. }
  585.  
  586. int c_dfru(bs,bt)                               /* Dictionary/Fold/Reverse  */
  587. char *bs, *bt;
  588. {
  589.     return c_dfu(bt,bs);
  590. }
  591.  
  592. int c_dru(bs,bt)                                /* Dictionary/Reverse       */
  593. char *bs, *bt;
  594. {
  595.     return c_du(bt,bs);
  596. }
  597.  
  598. int c_ibfru(bs,bt)                              /* Norm/Blank/Fold/Reverse  */
  599. register char *bs, *bt;
  600. {
  601.     SKIPSPACE(bs,bt);
  602.     return c_ifu(bt,bs);
  603. }
  604.  
  605. int c_ibfu(bs,bt)                               /* Normalized/Blank/Fold    */
  606. register char *bs, *bt;
  607. {
  608.     SKIPSPACE(bs,bt);
  609.     return c_ifu(bs,bt);
  610. }
  611.  
  612. int c_ibru(bs,bt)                               /* Normalized/Blank/Reverse */
  613. register char *bs, *bt;
  614. {
  615.     SKIPSPACE(bs,bt);
  616.     return c_iu(bt,bs);
  617. }
  618.  
  619. int c_ibu(bs,bt)                                /* Normalized/Blank         */
  620. register char *bs, *bt;
  621. {
  622.     SKIPSPACE(bs,bt);
  623.     return c_iu(bs,bt);
  624. }
  625.  
  626. int c_ifru(bs,bt)                               /* Normalized/Fold/Reverse  */
  627. char *bs, *bt;
  628. {
  629.     return c_ifu(bt,bs);
  630. }
  631.  
  632. int c_iru(bs,bt)                                /* Normalized/Reverse       */
  633. char *bs, *bt;
  634. {
  635.     return c_iu(bt,bs);
  636. }
  637.  
  638. int c_abfru(bs,bt)                              /* Blank/Fold/Reverse       */
  639. register char *bs, *bt;
  640. {
  641.     SKIPSPACE(bs,bt);
  642.     return c_afu(bt,bs);
  643. }
  644.  
  645. int c_abfu(bs,bt)                               /* Blank/Fold               */
  646. register char *bs, *bt;
  647. {
  648.     SKIPSPACE(bs,bt);
  649.     return c_afu(bs,bt);
  650. }
  651.  
  652. int c_abru(bs,bt)                               /* Blank/Reverse            */
  653. register char *bs, *bt;
  654. {
  655.     SKIPSPACE(bs,bt);
  656.     return c_au(bt,bs);
  657. }
  658.  
  659. int c_abu(bs,bt)                                /* Blank                    */
  660. register char *bs, *bt;
  661. {
  662.     SKIPSPACE(bs,bt);
  663.     return c_au(bs,bt);
  664. }
  665.  
  666. int c_afru(bs,bt)                               /* Fold/Reverse             */
  667. register char *bs, *bt;
  668. {
  669.     register char *fld = fold;
  670.  
  671.     if (fld[*bs] == fld[*bt] && *bt) {
  672.         for ( ; fld[*++bs] == fld[*++bt] && *bt; ) ;
  673.     }
  674.  
  675.     return fld[*bt] - fld[*bs];
  676. }
  677.  
  678. int c_aru(bs,bt)                                /* Reverse                  */
  679. register char *bs, *bt;
  680. {
  681.     if (*bs == *bt && *bt) {
  682.         for ( ; *++bs == *++bt && *bt; ) ;
  683.     }
  684.  
  685.     return *bt - *bs;
  686. }
  687.  
  688. int c_au(bs,bt)                                 /* Ordinary sort            */
  689. register char *bs, *bt;
  690. {
  691.     if (*bs == *bt && *bs) {                    /* Compare & skip eq. chars */
  692.         while (*++bs == *++bt && *bs) ;         /* Compare & skip eq. chars */
  693.     }
  694.  
  695.     return *bs - *bt;
  696. }
  697.  
  698. int c_a(bs,bt,es,et)                            /* Ordinary sort            */
  699. register char *bs, *bt;
  700. register char *es, *et;
  701. {
  702.     register short minlen;
  703.  
  704.     minlen = ((es - bs) <= (et - bt)) ? (es - bs) : (et - bt);
  705.     if (minlen == 0) {
  706.         return (es - bs) - (et - bt);
  707.     }
  708.  
  709.     if (*bs == *bt) {
  710.         for ( ; --minlen != 0 && *++bs == *++bt; ) ;
  711.         if (minlen == 0) {
  712.             return 0;
  713.         }
  714.     }
  715.  
  716.     return *bs - *bt;
  717. }
  718. #endif not MC68000
  719.